using System;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using StackExchange.Redis;

namespace RedisTestGUI
{
    public partial class RedisTestGUI : Form
    {
        private ConnectionMultiplexer redis;
        private IDatabase database;
        private readonly string RedisConnectionString = "192.168.8.100:6379,password=DRC@1234bank,abortConnect=false,connectTimeout=10000,syncTimeout=10000";
        private readonly string RedisQueueKey = "stock_buy_list";
        private readonly string RedisHistoryKey = "stock_buy_history";
        private readonly string ConsumerStatusKey = "stock_consumers";
        private Timer refreshTimer;

        // 控件声明
        private TextBox txtStockCode;
        private TextBox txtQuantity;
        private DateTimePicker dtpExecuteTime;
        private Button btnAddTask;
        private Button btnConnect;
        private Button btnDisconnect;
        private Button btnClearQueue;
        private ListBox lstTasks;
        private ListBox lstHistory;
        private ListBox lstConsumers;
        private Label lblStatus;
        private Label lblQueueCount;
        private Label lblCurrentTime;
        private Label lblConsumerCount;
        private Button btnKillConsumer;
        private Button btnRefreshConsumers;
        private Label lblRefreshStatus;
        private bool isUserInteractingWithConsumers = false;

        public RedisTestGUI()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();

            // 窗体设置
            this.Text = "同花顺买入任务测试工具";
            this.Size = new Size(1200, 800);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;

            // 连接状态标签
            lblStatus = new Label();
            lblStatus.Text = "状态: 未连接";
            lblStatus.Location = new Point(20, 20);
            lblStatus.Size = new Size(200, 25);
            lblStatus.ForeColor = Color.Red;
            this.Controls.Add(lblStatus);

            // 队列数量标签
            lblQueueCount = new Label();
            lblQueueCount.Text = "队列任务数: 0";
            lblQueueCount.Location = new Point(250, 20);
            lblQueueCount.Size = new Size(120, 25);
            this.Controls.Add(lblQueueCount);

            // 消费者数量标签
            lblConsumerCount = new Label();
            lblConsumerCount.Text = "消费者数: 0";
            lblConsumerCount.Location = new Point(380, 20);
            lblConsumerCount.Size = new Size(100, 25);
            this.Controls.Add(lblConsumerCount);

            // 当前时间标签
            lblCurrentTime = new Label();
            lblCurrentTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            lblCurrentTime.Location = new Point(500, 20);
            lblCurrentTime.Size = new Size(200, 25);
            lblCurrentTime.Font = new Font("Consolas", 10, FontStyle.Bold);
            lblCurrentTime.ForeColor = Color.Blue;
            this.Controls.Add(lblCurrentTime);

            // 连接按钮
            btnConnect = new Button();
            btnConnect.Text = "连接Redis";
            btnConnect.Location = new Point(720, 15);
            btnConnect.Size = new Size(80, 30);
            btnConnect.Click += BtnConnect_Click;
            this.Controls.Add(btnConnect);

            // 断开连接按钮
            btnDisconnect = new Button();
            btnDisconnect.Text = "断开连接";
            btnDisconnect.Location = new Point(810, 15);
            btnDisconnect.Size = new Size(80, 30);
            btnDisconnect.Enabled = false;
            btnDisconnect.Click += BtnDisconnect_Click;
            this.Controls.Add(btnDisconnect);

            // 刷新消费者按钮
            btnRefreshConsumers = new Button();
            btnRefreshConsumers.Text = "刷新消费者";
            btnRefreshConsumers.Location = new Point(900, 15);
            btnRefreshConsumers.Size = new Size(90, 30);
            btnRefreshConsumers.Enabled = false;
            btnRefreshConsumers.Click += BtnRefreshConsumers_Click;
            this.Controls.Add(btnRefreshConsumers);

            // 终止消费者按钮
            btnKillConsumer = new Button();
            btnKillConsumer.Text = "终止选中";
            btnKillConsumer.Location = new Point(1000, 15);
            btnKillConsumer.Size = new Size(80, 30);
            btnKillConsumer.BackColor = Color.LightCoral;
            btnKillConsumer.Enabled = false;
            btnKillConsumer.Click += BtnKillConsumer_Click;
            this.Controls.Add(btnKillConsumer);

            // 股票代码标签和输入框
            Label lblStockCode = new Label();
            lblStockCode.Text = "股票代码:";
            lblStockCode.Location = new Point(20, 70);
            lblStockCode.Size = new Size(80, 25);
            this.Controls.Add(lblStockCode);

            txtStockCode = new TextBox();
            txtStockCode.Location = new Point(100, 70);
            txtStockCode.Size = new Size(120, 25);
            txtStockCode.Text = "000001";
            this.Controls.Add(txtStockCode);

            // 数量标签和输入框
            Label lblQuantity = new Label();
            lblQuantity.Text = "买入数量:";
            lblQuantity.Location = new Point(250, 70);
            lblQuantity.Size = new Size(80, 25);
            this.Controls.Add(lblQuantity);

            txtQuantity = new TextBox();
            txtQuantity.Location = new Point(330, 70);
            txtQuantity.Size = new Size(120, 25);
            txtQuantity.Text = "100";
            this.Controls.Add(txtQuantity);

            // 执行时间标签和选择器
            Label lblExecuteTime = new Label();
            lblExecuteTime.Text = "执行时间:";
            lblExecuteTime.Location = new Point(20, 110);
            lblExecuteTime.Size = new Size(80, 25);
            this.Controls.Add(lblExecuteTime);

            dtpExecuteTime = new DateTimePicker();
            dtpExecuteTime.Format = DateTimePickerFormat.Time;
            dtpExecuteTime.ShowUpDown = true;
            dtpExecuteTime.Location = new Point(100, 110);
            dtpExecuteTime.Size = new Size(120, 25);
            dtpExecuteTime.Value = DateTime.Now.AddMinutes(1); // 默认1分钟后执行
            this.Controls.Add(dtpExecuteTime);

            // 添加任务按钮
            btnAddTask = new Button();
            btnAddTask.Text = "添加任务";
            btnAddTask.Location = new Point(250, 110);
            btnAddTask.Size = new Size(100, 30);
            btnAddTask.BackColor = Color.LightGreen;
            btnAddTask.Enabled = false;
            btnAddTask.Click += BtnAddTask_Click;
            this.Controls.Add(btnAddTask);

            // 清空队列按钮
            btnClearQueue = new Button();
            btnClearQueue.Text = "清空队列";
            btnClearQueue.Location = new Point(370, 110);
            btnClearQueue.Size = new Size(100, 30);
            btnClearQueue.BackColor = Color.LightCoral;
            btnClearQueue.Enabled = false;
            btnClearQueue.Click += BtnClearQueue_Click;
            this.Controls.Add(btnClearQueue);

            // 待执行任务列表
            Label lblTaskList = new Label();
            lblTaskList.Text = "待执行任务列表:";
            lblTaskList.Location = new Point(20, 160);
            lblTaskList.Size = new Size(150, 25);
            this.Controls.Add(lblTaskList);

            lstTasks = new ListBox();
            lstTasks.Location = new Point(20, 190);
            lstTasks.Size = new Size(550, 120);
            lstTasks.Font = new Font("Consolas", 9);
            lstTasks.Items.Add("请先连接Redis服务器");
            this.Controls.Add(lstTasks);

            // 消费者状态列表
            Label lblConsumerList = new Label();
            lblConsumerList.Text = "消费者状态列表:";
            lblConsumerList.Location = new Point(590, 160);
            lblConsumerList.Size = new Size(150, 25);
            this.Controls.Add(lblConsumerList);

            // 刷新状态标签
            lblRefreshStatus = new Label();
            lblRefreshStatus.Text = "🔄 自动刷新";
            lblRefreshStatus.Location = new Point(750, 160);
            lblRefreshStatus.Size = new Size(100, 25);
            lblRefreshStatus.ForeColor = Color.Green;
            lblRefreshStatus.Font = new Font("Microsoft YaHei", 9);
            this.Controls.Add(lblRefreshStatus);

            lstConsumers = new ListBox();
            lstConsumers.Location = new Point(590, 190);
            lstConsumers.Size = new Size(580, 120);
            lstConsumers.Font = new Font("Consolas", 9);
            lstConsumers.Items.Add("请先连接Redis服务器");
            // 添加鼠标和键盘事件处理
            lstConsumers.MouseDown += LstConsumers_MouseDown;
            lstConsumers.KeyDown += LstConsumers_KeyDown;
            lstConsumers.Leave += LstConsumers_Leave;
            lstConsumers.SelectedIndexChanged += LstConsumers_SelectedIndexChanged;
            this.Controls.Add(lstConsumers);

            // 历史执行任务列表
            Label lblHistoryList = new Label();
            lblHistoryList.Text = "今日历史执行任务:";
            lblHistoryList.Location = new Point(20, 330);
            lblHistoryList.Size = new Size(150, 25);
            this.Controls.Add(lblHistoryList);

            lstHistory = new ListBox();
            lstHistory.Location = new Point(20, 360);
            lstHistory.Size = new Size(1150, 150);
            lstHistory.Font = new Font("Consolas", 9);
            lstHistory.Items.Add("暂无历史执行记录");
            this.Controls.Add(lstHistory);

            // 快捷添加按钮组
            GroupBox gbQuickAdd = new GroupBox();
            gbQuickAdd.Text = "快捷添加";
            gbQuickAdd.Location = new Point(20, 530);
            gbQuickAdd.Size = new Size(1150, 60);
            this.Controls.Add(gbQuickAdd);

            Button btnAdd1Min = new Button();
            btnAdd1Min.Text = "1分钟后";
            btnAdd1Min.Location = new Point(10, 20);
            btnAdd1Min.Size = new Size(80, 30);
            btnAdd1Min.Click += (s, e) => QuickAddTask(1);
            gbQuickAdd.Controls.Add(btnAdd1Min);

            Button btnAdd5Min = new Button();
            btnAdd5Min.Text = "5分钟后";
            btnAdd5Min.Location = new Point(100, 20);
            btnAdd5Min.Size = new Size(80, 30);
            btnAdd5Min.Click += (s, e) => QuickAddTask(5);
            gbQuickAdd.Controls.Add(btnAdd5Min);

            Button btnAdd930 = new Button();
            btnAdd930.Text = "明天9:30";
            btnAdd930.Location = new Point(190, 20);
            btnAdd930.Size = new Size(80, 30);
            btnAdd930.Click += (s, e) => QuickAddTask("09:30:00");
            gbQuickAdd.Controls.Add(btnAdd930);

            Button btnAdd1000 = new Button();
            btnAdd1000.Text = "明天10:00";
            btnAdd1000.Location = new Point(280, 20);
            btnAdd1000.Size = new Size(80, 30);
            btnAdd1000.Click += (s, e) => QuickAddTask("10:00:00");
            gbQuickAdd.Controls.Add(btnAdd1000);

            Button btnAddNow = new Button();
            btnAddNow.Text = "立即执行";
            btnAddNow.Location = new Point(370, 20);
            btnAddNow.Size = new Size(80, 30);
            btnAddNow.BackColor = Color.Yellow;
            btnAddNow.Click += (s, e) => QuickAddTask(0);
            gbQuickAdd.Controls.Add(btnAddNow);

            this.ResumeLayout(false);
        }

        private async void BtnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                btnConnect.Enabled = false;
                lblStatus.Text = "状态: 连接中...";
                lblStatus.ForeColor = Color.Orange;

                redis = await ConnectionMultiplexer.ConnectAsync(RedisConnectionString);
                database = redis.GetDatabase();

                // 测试连接
                await database.PingAsync();

                lblStatus.Text = "状态: 已连接";
                lblStatus.ForeColor = Color.Green;
                btnConnect.Enabled = false;
                btnDisconnect.Enabled = true;
                btnAddTask.Enabled = true;
                btnClearQueue.Enabled = true;
                btnRefreshConsumers.Enabled = true;
                btnKillConsumer.Enabled = true;

                await UpdateQueueCount();
                await RefreshTaskList();
                await RefreshHistoryList();
                await RefreshConsumerList();
                
                // 启动定时器，每秒刷新
                StartRefreshTimer();
                
                MessageBox.Show("Redis连接成功！", "连接成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                lblStatus.Text = "状态: 连接失败";
                lblStatus.ForeColor = Color.Red;
                btnConnect.Enabled = true;
                MessageBox.Show($"Redis连接失败:\n{ex.Message}", "连接失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void BtnDisconnect_Click(object sender, EventArgs e)
        {
            try
            {
                // 停止定时器
                StopRefreshTimer();
                
                redis?.Dispose();
                redis = null;
                database = null;

                lblStatus.Text = "状态: 未连接";
                lblStatus.ForeColor = Color.Red;
                lblQueueCount.Text = "队列任务数: 0";
                lblConsumerCount.Text = "消费者数: 0";
                btnConnect.Enabled = true;
                btnDisconnect.Enabled = false;
                btnAddTask.Enabled = false;
                btnClearQueue.Enabled = false;
                btnRefreshConsumers.Enabled = false;
                btnKillConsumer.Enabled = false;
                lstTasks.Items.Clear();
                lstTasks.Items.Add("请先连接Redis服务器");
                lstHistory.Items.Clear();
                lstHistory.Items.Add("暂无历史执行记录");
                lstConsumers.Items.Clear();
                lstConsumers.Items.Add("请先连接Redis服务器");

                MessageBox.Show("已断开Redis连接", "断开连接", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"断开连接时出错:\n{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private async void BtnAddTask_Click(object sender, EventArgs e)
        {
            try
            {
                if (!ValidateInput())
                    return;

                string stockCode = txtStockCode.Text.Trim();
                int quantity = int.Parse(txtQuantity.Text.Trim());
                string executeTime = dtpExecuteTime.Value.ToString("HH:mm:ss");

                string taskString = $"{stockCode}|{quantity}|{executeTime}";

                await database.ListLeftPushAsync(RedisQueueKey, taskString);

                await UpdateQueueCount();
                await RefreshTaskList();
                
                MessageBox.Show($"任务添加成功！\n股票代码: {stockCode}\n买入数量: {quantity}股\n执行时间: {executeTime}", 
                    "添加成功", MessageBoxButtons.OK, MessageBoxIcon.Information);

               
            }
            catch (Exception ex)
            {
                MessageBox.Show($"添加任务失败:\n{ex.Message}", "添加失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private async void BtnClearQueue_Click(object sender, EventArgs e)
        {
            try
            {
                var result = MessageBox.Show("确定要清空所有待执行任务吗？", "确认清空", 
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if (result == DialogResult.Yes)
                {
                    // 在清空前，将任务移动到历史记录
                    await MoveTasksToHistory();
                    
                    await database.KeyDeleteAsync(RedisQueueKey);
                    await UpdateQueueCount();
                    await RefreshTaskList();
                    MessageBox.Show("队列清空成功！所有任务已移至历史记录。", "清空成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"清空队列失败:\n{ex.Message}", "清空失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void QuickAddTask(int minutesFromNow)
        {
            DateTime executeTime = DateTime.Now.AddMinutes(minutesFromNow);
            dtpExecuteTime.Value = executeTime;
            BtnAddTask_Click(null, null);
        }

        private void QuickAddTask(string timeString)
        {
            TimeSpan time = TimeSpan.Parse(timeString);
            DateTime tomorrow = DateTime.Today.AddDays(1).Add(time);
            dtpExecuteTime.Value = tomorrow;
            BtnAddTask_Click(null, null);
        }

        private async Task UpdateQueueCount()
        {
            try
            {
                if (database != null)
                {
                    long count = await database.ListLengthAsync(RedisQueueKey);
                    lblQueueCount.Text = $"队列任务数: {count}";
                }
            }
            catch (Exception)
            {
                lblQueueCount.Text = "队列任务数: 获取失败";
            }
        }

        private async Task RefreshTaskList()
        {
            try
            {
                if (database != null)
                {
                    lstTasks.Items.Clear();
                    
                    // 获取队列中的所有任务
                    var tasks = await database.ListRangeAsync(RedisQueueKey);
                    
                    if (tasks.Length == 0)
                    {
                        lstTasks.Items.Add("队列中暂无待执行任务");
                        return;
                    }

                    lstTasks.Items.Add("=== Redis队列中的待执行任务 ===");
                    
                    for (int i = 0; i < tasks.Length; i++)
                    {
                        string taskString = tasks[i];
                        if (!string.IsNullOrEmpty(taskString))
                        {
                            // 解析任务字符串: stockCode|quantity|executeTime
                            string[] parts = taskString.ToString().Split('|');
                            if (parts.Length >= 3)
                            {
                                string stockCode = parts[0];
                                string quantity = parts[1];
                                string executeTime = parts[2];
                                
                                lstTasks.Items.Add($"[{i + 1:D2}] 股票:{stockCode} | 数量:{quantity}股 | 执行时间:{executeTime}");
                            }
                            else
                            {
                                lstTasks.Items.Add($"[{i + 1:D2}] {taskString}");
                            }
                        }
                    }
                    
                    lstTasks.Items.Add($"--- 共 {tasks.Length} 个待执行任务 ---");
                }
            }
            catch (Exception ex)
            {
                lstTasks.Items.Clear();
                lstTasks.Items.Add($"获取任务列表失败: {ex.Message}");
            }
        }

        private async Task RefreshHistoryList()
        {
            try
            {
                if (database != null)
                {
                    lstHistory.Items.Clear();
                    
                    // 获取今日历史任务，使用日期作为键的后缀
                    string todayKey = $"{RedisHistoryKey}:{DateTime.Today:yyyyMMdd}";
                    var historyTasks = await database.ListRangeAsync(todayKey);
                    
                    if (historyTasks.Length == 0)
                    {
                        lstHistory.Items.Add("今日暂无历史执行记录");
                        return;
                    }

                    lstHistory.Items.Add("=== 今日历史执行任务 ===");
                    
                    // 倒序显示，最新的在前面
                    for (int i = historyTasks.Length - 1; i >= 0; i--)
                    {
                        string taskString = historyTasks[i];
                        if (!string.IsNullOrEmpty(taskString))
                        {
                            // 解析历史任务字符串: stockCode|quantity|executeTime|actualTime
                            string[] parts = taskString.ToString().Split('|');
                            if (parts.Length >= 4)
                            {
                                string stockCode = parts[0];
                                string quantity = parts[1];
                                string executeTime = parts[2];
                                string actualTime = parts[3];
                                
                                lstHistory.Items.Add($"[{historyTasks.Length - i:D2}] {actualTime} 执行: 股票{stockCode} | {quantity}股 | 计划时间:{executeTime}");
                            }
                            else
                            {
                                lstHistory.Items.Add($"[{historyTasks.Length - i:D2}] {taskString}");
                            }
                        }
                    }
                    
                    lstHistory.Items.Add($"--- 今日共执行 {historyTasks.Length} 个任务 ---");
                }
            }
            catch (Exception ex)
            {
                lstHistory.Items.Clear();
                lstHistory.Items.Add($"获取历史任务失败: {ex.Message}");
            }
        }

        private void StartRefreshTimer()
        {
            refreshTimer = new Timer();
            refreshTimer.Interval = 1000; // 每秒刷新
            refreshTimer.Tick += RefreshTimer_Tick;
            refreshTimer.Start();
        }

        private void StopRefreshTimer()
        {
            refreshTimer?.Stop();
            refreshTimer?.Dispose();
            refreshTimer = null;
        }

        private async void RefreshTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                // 更新时间显示
                lblCurrentTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                
                // 刷新任务列表和历史列表
                if (database != null)
                {
                    await UpdateQueueCount();
                    await RefreshTaskList();
                    await RefreshHistoryList();
                    
                    // 只有在用户没有与消费者列表交互时才自动刷新
                    if (!isUserInteractingWithConsumers)
                    {
                        await RefreshConsumerList();
                    }
                }
            }
            catch (Exception ex)
            {
                // 静默处理定时器异常，避免频繁弹窗
                lblStatus.Text = $"状态: 刷新异常 - {ex.Message}";
            }
        }

        private async Task MoveTasksToHistory()
        {
            try
            {
                if (database != null)
                {
                    // 获取所有待执行任务
                    var tasks = await database.ListRangeAsync(RedisQueueKey);
                    
                    if (tasks.Length > 0)
                    {
                        string todayKey = $"{RedisHistoryKey}:{DateTime.Today:yyyyMMdd}";
                        string currentTime = DateTime.Now.ToString("HH:mm:ss");
                        
                        // 将每个任务添加到历史记录
                        foreach (var task in tasks)
                        {
                            if (!string.IsNullOrEmpty(task))
                            {
                                // 在原任务字符串后添加实际执行时间
                                string historyTask = $"{task}|{currentTime}";
                                await database.ListLeftPushAsync(todayKey, historyTask);
                            }
                        }
                        
                        // 设置历史记录的过期时间（7天）
                        await database.KeyExpireAsync(todayKey, TimeSpan.FromDays(7));
                    }
                }
            }
            catch (Exception ex)
            {
                // 记录错误但不中断流程
                lblStatus.Text = $"状态: 移动任务到历史记录失败 - {ex.Message}";
            }
        }

        private bool ValidateInput()
        {
            if (string.IsNullOrWhiteSpace(txtStockCode.Text))
            {
                MessageBox.Show("请输入股票代码", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtStockCode.Focus();
                return false;
            }

            if (txtStockCode.Text.Trim().Length != 6)
            {
                MessageBox.Show("股票代码必须是6位数字", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtStockCode.Focus();
                return false;
            }

            if (!int.TryParse(txtQuantity.Text, out int quantity) || quantity <= 0)
            {
                MessageBox.Show("请输入有效的买入数量", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtQuantity.Focus();
                return false;
            }

            return true;
        }

        private string ExtractJsonValue(string json, string key)
        {
            try
            {
                string pattern = $"\"{key}\":\"";
                int startIndex = json.IndexOf(pattern);
                if (startIndex == -1)
                {
                    // 尝试数字类型（不带引号）
                    pattern = $"\"{key}\":";
                    startIndex = json.IndexOf(pattern);
                    if (startIndex == -1) return "";
                    
                    startIndex += pattern.Length;
                    int numEndIndex = json.IndexOfAny(new char[] { ',', '}' }, startIndex);
                    if (numEndIndex == -1) return "";
                    
                    return json.Substring(startIndex, numEndIndex - startIndex).Trim();
                }
                
                startIndex += pattern.Length;
                int strEndIndex = json.IndexOf("\"", startIndex);
                if (strEndIndex == -1) return "";
                
                return json.Substring(startIndex, strEndIndex - startIndex);
            }
            catch
            {
                return "";
            }
        }

        // 消费者列表交互事件处理
        private void LstConsumers_MouseDown(object sender, MouseEventArgs e)
        {
            isUserInteractingWithConsumers = true;
            // 5秒后自动恢复刷新
            System.Windows.Forms.Timer resumeTimer = new System.Windows.Forms.Timer();
            resumeTimer.Interval = 5000; // 5秒
            resumeTimer.Tick += (s, ev) => {
                resumeTimer.Stop();
                resumeTimer.Dispose();
                if (lstConsumers.SelectedIndex == -1) // 如果没有选中项，恢复自动刷新
                {
                    isUserInteractingWithConsumers = false;
                }
            };
            resumeTimer.Start();
        }

        private void LstConsumers_KeyDown(object sender, KeyEventArgs e)
        {
            isUserInteractingWithConsumers = true;
            // 3秒后自动恢复刷新
            System.Windows.Forms.Timer resumeTimer = new System.Windows.Forms.Timer();
            resumeTimer.Interval = 3000; // 3秒
            resumeTimer.Tick += (s, ev) => {
                resumeTimer.Stop();
                resumeTimer.Dispose();
                if (lstConsumers.SelectedIndex == -1) // 如果没有选中项，恢复自动刷新
                {
                    isUserInteractingWithConsumers = false;
                }
            };
            resumeTimer.Start();
        }

        private void LstConsumers_Leave(object sender, EventArgs e)
        {
            // 当控件失去焦点且没有选中项时，恢复自动刷新
            if (lstConsumers.SelectedIndex == -1)
            {
                isUserInteractingWithConsumers = false;
            }
        }

        private void LstConsumers_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 如果有选中项，暂停自动刷新；如果取消选中，恢复自动刷新
            if (lstConsumers.SelectedIndex >= 0)
            {
                isUserInteractingWithConsumers = true;
                lblRefreshStatus.Text = "⏸️ 暂停刷新";
                lblRefreshStatus.ForeColor = Color.Orange;
            }
            else
            {
                isUserInteractingWithConsumers = false;
                lblRefreshStatus.Text = "🔄 自动刷新";
                lblRefreshStatus.ForeColor = Color.Green;
            }
        }

        private async Task RefreshConsumerList()
        {
            try
            {
                if (database != null)
                {
                    // 保存当前选中的项目
                    int selectedIndex = lstConsumers.SelectedIndex;
                    string selectedItem = selectedIndex >= 0 && selectedIndex < lstConsumers.Items.Count 
                        ? lstConsumers.Items[selectedIndex].ToString() 
                        : null;
                    
                    lstConsumers.Items.Clear();
                    
                    // 获取所有消费者状态
                    var consumers = await database.HashGetAllAsync(ConsumerStatusKey);
                    
                    if (consumers.Length == 0)
                    {
                        lstConsumers.Items.Add("当前无消费者程序运行");
                        lblConsumerCount.Text = "消费者数: 0";
                        return;
                    }

                    lstConsumers.Items.Add("=== 消费者程序状态 ===");
                    
                    int activeCount = 0;
                    foreach (var consumer in consumers)
                    {
                        try
                        {
                            string jsonData = consumer.Value;
                            
                            // 简单的JSON解析
                            string id = ExtractJsonValue(jsonData, "id");
                            string hostname = ExtractJsonValue(jsonData, "hostname");
                            string status = ExtractJsonValue(jsonData, "status");
                            string currentTask = ExtractJsonValue(jsonData, "current_task");
                            long lastUpdate = long.Parse(ExtractJsonValue(jsonData, "last_update"));
                            int processId = int.Parse(ExtractJsonValue(jsonData, "process_id"));
                            
                            DateTime lastUpdateTime = DateTimeOffset.FromUnixTimeSeconds(lastUpdate).LocalDateTime;
                            TimeSpan timeSinceUpdate = DateTime.Now - lastUpdateTime;
                            
                            string statusText;
                            switch (status)
                            {
                                case "idle":
                                    statusText = "空闲";
                                    break;
                                case "executing":
                                    statusText = "执行中";
                                    break;
                                case "error":
                                    statusText = "错误";
                                    break;
                                default:
                                    statusText = status;
                                    break;
                            }
                            
                            string itemText = $"[{hostname}] PID:{processId} | 状态:{statusText}";
                            if (!string.IsNullOrEmpty(currentTask))
                            {
                                itemText += $" | 任务:{currentTask}";
                            }
                            itemText += $" | 更新:{timeSinceUpdate.TotalSeconds:F0}秒前";
                            
                            // 如果超过30秒没更新，标记为可能离线
                            if (timeSinceUpdate.TotalSeconds > 30)
                            {
                                itemText += " [可能离线]";
                            }
                            else
                            {
                                activeCount++;
                            }
                            
                            lstConsumers.Items.Add(itemText);
                        }
                        catch (Exception ex)
                        {
                            lstConsumers.Items.Add($"解析消费者数据失败: {consumer.Name} - {ex.Message}");
                        }
                    }
                    
                    lblConsumerCount.Text = $"消费者数: {activeCount}/{consumers.Length}";
                    lstConsumers.Items.Add($"--- 共 {consumers.Length} 个注册消费者，{activeCount} 个活跃 ---");
                    
                    // 尝试恢复之前选中的项目
                    if (!string.IsNullOrEmpty(selectedItem))
                    {
                        for (int i = 0; i < lstConsumers.Items.Count; i++)
                        {
                            string currentItem = lstConsumers.Items[i].ToString();
                            // 通过PID匹配来恢复选择（因为其他信息可能会变化）
                            if (selectedItem.Contains("PID:") && currentItem.Contains("PID:"))
                            {
                                var selectedPid = ExtractPidFromText(selectedItem);
                                var currentPid = ExtractPidFromText(currentItem);
                                if (!string.IsNullOrEmpty(selectedPid) && selectedPid == currentPid)
                                {
                                    lstConsumers.SelectedIndex = i;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                lstConsumers.Items.Clear();
                lstConsumers.Items.Add($"获取消费者列表失败: {ex.Message}");
                lblConsumerCount.Text = "消费者数: 获取失败";
            }
        }

        private string ExtractPidFromText(string text)
        {
            try
            {
                var match = System.Text.RegularExpressions.Regex.Match(text, @"PID:(\d+)");
                return match.Success ? match.Groups[1].Value : "";
            }
            catch
            {
                return "";
            }
        }

        private async void BtnRefreshConsumers_Click(object sender, EventArgs e)
        {
            try
            {
                // 手动刷新时，重置交互状态并强制刷新
                isUserInteractingWithConsumers = false;
                await RefreshConsumerList();
                MessageBox.Show("消费者列表已刷新，自动更新已恢复", "刷新成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"刷新消费者列表失败:\n{ex.Message}", "刷新失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private async void BtnKillConsumer_Click(object sender, EventArgs e)
        {
            try
            {
                if (lstConsumers.SelectedIndex < 0)
                {
                    MessageBox.Show("请先选择要终止的消费者", "选择错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                string selectedItem = lstConsumers.SelectedItem.ToString();
                if (selectedItem.Contains("===") || selectedItem.Contains("---") || selectedItem.Contains("获取失败") || selectedItem.Contains("无消费者"))
                {
                    MessageBox.Show("请选择有效的消费者项目", "选择错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                var result = MessageBox.Show($"确定要终止选中的消费者吗？\n\n{selectedItem}\n\n注意：这将强制终止消费者进程！", 
                    "确认终止", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if (result == DialogResult.Yes)
                {
                    // 从选中的文本中提取PID
                    var match = System.Text.RegularExpressions.Regex.Match(selectedItem, @"PID:(\d+)");
                    if (match.Success && int.TryParse(match.Groups[1].Value, out int pid))
                    {
                        try
                        {
                            var process = System.Diagnostics.Process.GetProcessById(pid);
                            process.Kill();
                            process.WaitForExit(5000);
                            
                            MessageBox.Show($"消费者进程 PID:{pid} 已被终止", "终止成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            
                            // 刷新列表
                            await Task.Delay(1000); // 等待一秒让Redis状态更新
                            await RefreshConsumerList();
                        }
                        catch (ArgumentException)
                        {
                            MessageBox.Show($"进程 PID:{pid} 不存在或已经终止", "进程不存在", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            await RefreshConsumerList();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show($"终止进程失败:\n{ex.Message}", "终止失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show("无法从选中项目中提取进程ID", "解析错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"终止消费者失败:\n{ex.Message}", "操作失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            StopRefreshTimer();
            redis?.Dispose();
            base.OnFormClosing(e);
        }
    }

    // 程序入口
    public class GUIProgram
    {
        [STAThread]
        public static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new RedisTestGUI());
        }
    }
}
